﻿Class CommandQueue
    Private commandList As List(Of Command)

    Public Sub addCommands(ByRef aCommandList As List(Of Command))
        If commandList Is Nothing Then
            commandList = New List(Of Command)
        End If
        For Each Command In aCommandList
            commandList.Add(Command)
        Next
    End Sub

    Public Function isEmpty() As Boolean
        Return commandList Is Nothing OrElse commandList.Count = 0
    End Function

    Public Function popOutNextExecutableCommand() As Command
        If isEmpty() Then
            Return Nothing
        End If
        Dim commandToPopUp = getNextExecutableCommand()
        If Not commandToPopUp Is Nothing Then
            removeFromList(commandToPopUp)
        End If
        Return commandToPopUp
    End Function

    Private Function getNextExecutableCommand() As Command
        Dim threadSaveCopyOfList = getThreadSafeCopyOfCommandList()
        For Each Command In threadSaveCopyOfList
            If Command.canBeExecuted() Then
                Return Command
            End If
        Next
        Return Nothing
    End Function

    Private Function getThreadSafeCopyOfCommandList() As List(Of Command)
        Dim threadSaveCopyOfList As List(Of Command)
        Dim synchList = ArrayList.Synchronized(commandList)
        SyncLock synchList
            threadSaveCopyOfList = New List(Of Command)(commandList)
        End SyncLock
        Return threadSaveCopyOfList
    End Function

    Private Sub removeFromList(ByRef command As Command)
        Dim synchList = ArrayList.Synchronized(commandList)
        synchList.Remove(command)
    End Sub

End Class
